package com.hexacta.hrs.test.data;

import java.util.Calendar;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.vectrics.employee.Employee;

import com.hexacta.hrs.domain.mentoring.Action;
import com.hexacta.hrs.domain.mentoring.Meeting;
import com.hexacta.hrs.domain.mentoring.MeetingStatus;
import com.hexacta.hrs.domain.mentoring.PriorityTypes;
import com.hexacta.hrs.domain.mentoring.Theme;
import com.hexacta.hrs.domain.mentoring.ThemeTypes;

/**
 * Test data dependency creator for the Meeting class.
 * <p>
 * TODO We should review this if we want more meaningful data.
 * 
 * @author vschimpf
 */
public class MeetingTestDataDependencyCreator extends AbstractTestDataDependencyCreator {

    public static final String MEETING_1 = "MEETING_1";

    public static final String MEETING_2 = "MEETING_2";

    public static final String MEETING_3 = "MEETING_3";

    public static final String MEETING_4 = "MEETING_4";

    public static final String MEETING_5 = "MEETING_5";

    public MeetingTestDataDependencyCreator(final List<TestDataDependencyCreator> dependencies) {
        super(dependencies);
    }

    public void createDependentTestData(final Map<String, Object> context) {

        Meeting meeting1 = createMeeting(context, EmployeeTestDataDependencyCreator.EMPLOYEE_1,
                EmployeeTestDataDependencyCreator.EMPLOYEE_2, MeetingStatus.PERFORMED, getDateBefore());
        Meeting meeting2 = createMeeting(context, EmployeeTestDataDependencyCreator.EMPLOYEE_1,
                EmployeeTestDataDependencyCreator.EMPLOYEE_2, MeetingStatus.PERFORMED, getDateAfter());
        Meeting meeting3 = createMeeting(context, EmployeeTestDataDependencyCreator.EMPLOYEE_1,
                EmployeeTestDataDependencyCreator.EMPLOYEE_2, MeetingStatus.PERFORMED, getDateBetweenToAndFrom());

        Meeting meeting4 = createMeeting(context, EmployeeTestDataDependencyCreator.EMPLOYEE_3,
                EmployeeTestDataDependencyCreator.EMPLOYEE_4, MeetingStatus.SCHEDULED, getDateBySelectedMonth());
        Meeting meeting5 = createMeeting(context, EmployeeTestDataDependencyCreator.EMPLOYEE_3,
                EmployeeTestDataDependencyCreator.EMPLOYEE_5, MeetingStatus.SCHEDULED, getDateAfterSelectedMonth());

        meeting1 = this.insertDomainObject(meeting1);
        meeting3.setPreviousMeeting(meeting1);
        meeting3 = this.insertDomainObject(meeting3);
        meeting2.setPreviousMeeting(meeting3);
        meeting2 = this.insertDomainObject(meeting2);

        // TODO: Revisar si es correcto que 2 meeting esten scheduled.
        meeting4 = this.insertDomainObject(meeting4);
        meeting5.setPreviousMeeting(meeting4);
        meeting5 = this.insertDomainObject(meeting5);

        storeObjectReferenceInContext(context, MEETING_1, meeting1);
        storeObjectReferenceInContext(context, MEETING_2, meeting2);
        storeObjectReferenceInContext(context, MEETING_3, meeting3);
        storeObjectReferenceInContext(context, MEETING_4, meeting4);
        storeObjectReferenceInContext(context, MEETING_5, meeting5);
    }

    @Override
    public Set<Scenario> getApplicableScenarios() {
        return EnumSet.of(Scenario.DEVELOPMENT);
    }

    private Meeting createMeeting(final Map<String, Object> context, final String mentorToken,
            final String employeeToken, final MeetingStatus status, final Date date) {
        Employee mentor = (Employee) loadObjectFromContext(context, mentorToken);
        Employee employee = (Employee) loadObjectFromContext(context, employeeToken);

        if ((employee.getMentor() == null)
                || (!employee.getEmploymentConditionHistory().getCurrentMentor().getId().equals(mentor.getId()))) {
            employee.addMentorAssignment(mentor, date);// Active
            // relationship
        }

        Meeting meeting = new Meeting();
        meeting.setEmployee(employee);
        meeting.setMentor(mentor);
        meeting.setStatus(status);
        meeting.setDate(date);
        meeting.setCheckedByHR(true);

        Set<Theme> noteThemes = new HashSet<Theme>();
        Theme theme1 = new Theme();
        theme1.setName("Theme 1");
        theme1.setPriority(PriorityTypes.HIGH);
        theme1.setType(ThemeTypes.STAFFING);
        noteThemes.add(theme1);

        Theme theme2 = new Theme();
        theme2.setName("Theme 2");
        theme2.setPriority(PriorityTypes.MEDIUM);
        theme2.setType(ThemeTypes.TRAINNING);
        noteThemes.add(theme2);
        meeting.setNoteThemes(noteThemes);

        Set<Action> actions = new HashSet<Action>();
        Action action1 = new Action();
        action1.setName("Action 1");
        actions.add(action1);

        Action action2 = new Action();
        action2.setName("Action 2");
        actions.add(action2);
        meeting.setActionsToDo(actions);

        return meeting;
    }

    public static Integer getSelectedMonth() {
        return Calendar.APRIL;
    }

    public static Date getDateBySelectedMonth() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, 2009);
        c.set(Calendar.MONTH, getSelectedMonth());
        c.set(Calendar.DATE, 1);
        c.set(Calendar.HOUR, 1);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    public static Date getDateAfterSelectedMonth() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, 2009);
        c.set(Calendar.MONTH, getSelectedMonth() + 4);
        c.set(Calendar.DATE, 1);
        return c.getTime();
    }

    public static Date getDateFrom() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, 2009);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 1);
        return c.getTime();
    }

    public static Date getDateTo() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, 2009);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 15);
        return c.getTime();
    }

    public static Date getDateBetweenToAndFrom() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, 2009);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 8);
        return c.getTime();
    }

    public static Date getDateAfter() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, 2009);
        c.set(Calendar.MONTH, Calendar.JANUARY);
        c.set(Calendar.DATE, 30);
        return c.getTime();
    }

    public static Date getDateBefore() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, 2008);
        c.set(Calendar.MONTH, Calendar.DECEMBER);
        c.set(Calendar.DATE, 30);
        return c.getTime();
    }

}
